﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Castle.DynamicProxy;
using FluentValidation;
using FluentValidation.Results;

namespace TimeKeeper.Infrastructure
{
    public class DataErrorInfoInterceptor : PropertyChangedInterceptor
    {
        private readonly IValidator _validator;
        private ValidationResult _result;

        public DataErrorInfoInterceptor(IValidator validator)
        {
            _validator = validator;
        }

        public override void Intercept(IInvocation invocation)
        {
            if (invocation.Method.DeclaringType != null && invocation.Method.DeclaringType == typeof(IDataErrorInfo))
            {
                if (_result == null) _result = _validator.Validate(invocation.Proxy);

                if (_result.IsValid) //object is valid
                {
                    invocation.ReturnValue = string.Empty;
                    return;
                }

                switch (invocation.Method.Name)
                {
                    case "get_Item":
                        {
                            var propertyName = (string)invocation.Arguments[0];
                            var errors = _result.Errors.Where(x => x.PropertyName.Contains(propertyName));
                            invocation.ReturnValue = string.Join(Environment.NewLine, errors);
                        }
                        break;
                    case "get_Error":
                        {
                            var validationErrors = new StringBuilder();
                            foreach (var validationFailure in _result.Errors)
                            {
                                validationErrors.Append(validationFailure.ErrorMessage);
                                validationErrors.Append(Environment.NewLine);
                            }
                            invocation.ReturnValue = validationErrors.ToString();
                        }
                        break;
                }
                return;
            }

            base.Intercept(invocation);
        }

        protected override void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            _result = _validator.Validate(sender);
            base.OnPropertyChanged(sender, e);
        }
    }
}